package tmhm.main;

import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.StringTokenizer;

import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.ImageIcon;



import tmhm.assembler.Assembler;
import tmhm.assembler.Disassembler;
import tmhm.components.*;
import tmhm.gui.*;
//import debug.*;
import tmhm.shemes.*;

@SuppressWarnings("serial")
public class Main extends JFrame {

	 static int cnt = 0;
	 static String asmPath = "";
    private static StepsLoader st = new StepsLoader("conf/tmhm/microProgram.txt", null);
    public final JFileChooser fileChooserAsm =  new javax.swing.JFileChooser();;
    JPanel east = new JPanel();
    JScrollPane scrolltxt = new JScrollPane();
    JPanel northeast = new JPanel();
    JPanel southeast = new JPanel();
    JPanel west = new JPanel();
    
    
    private javax.swing.JPanel drawCanvas  = new javax.swing.JPanel();
    private JLabel signal1 = new javax.swing.JLabel();
    private JLabel signal2 = new javax.swing.JLabel();
    private JLabel signal3 = new javax.swing.JLabel();
    private JLabel signal4 = new javax.swing.JLabel();
    private JLabel signal5 = new javax.swing.JLabel();
    private JPanel signals = new javax.swing.JPanel();
    private JScrollPane JScroolPanelDraw = new javax.swing.JScrollPane();
    private JTable drawTable = new javax.swing.JTable();
    private JPanel Navigation = new javax.swing.JPanel();
    private JButton drawButton = new javax.swing.JButton();
    private JButton leftButton = new javax.swing.JButton();
    private JButton rightButton = new javax.swing.JButton();
    private JMenuBar menuBar = new javax.swing.JMenuBar();
    private JMenu file = new javax.swing.JMenu();
    private JMenuItem jMenuItem1 = new javax.swing.JMenuItem();
    private JMenu view = new javax.swing.JMenu();
    private JMenuItem jMenuItem2 = new javax.swing.JMenuItem();
    private JMenu help = new javax.swing.JMenu();
    private JMenuItem jMenuItem3 = new javax.swing.JMenuItem();
    
    JLabel CPUclock = new JLabel("CPU clock = 0");
    JLabel Tcpu = new JLabel("mPC = 0");
    JLabel PC = new JLabel("PC = 100");
    JButton btnOpenAsm = new JButton("  Open&Compile ");
    JButton CLK = new JButton("                 CLK+               ");
    JButton INS = new JButton("        INSTRUCTION+      ");
    JButton PRG = new JButton("          PROGRAM+          ");
    private javax.swing.JDialog diagram = new javax.swing.JDialog();
    JButton GOTO = new JButton("GO TO:");
    JTextField end = new JTextField();
    public JScrollPane scrollPane;
    // Labela za oznaku faze
    JLabel phaseName = new JLabel("Faza izvrsavanja:");
    // Labela koja kazuje fazu
    JLabel phase = new JLabel("-");
    // Labela za oznaku nacina adresiranja
    JLabel signsName = new JLabel("Microprogram:", JLabel.LEFT);
    // Labela koja prikazuje aktivnee signale
    JLabel signs = new JLabel("-", JLabel.LEFT);
    // treba dodati opcioju da se resetuje sistem na pocetno stanje
    JLabel asmtxt = new JLabel("Asemblerski kod:");
    JTextArea asmtext = new JTextArea();
    JButton load = new JButton("Compile");
    JButton reset = new JButton("RESET");
    JButton registers = new JButton("REGISTRY");
    JButton memory = new JButton("MEMORY");
    JButton resetnomem = new JButton("RESET WITHOUT MEM");
    JPanel menu = new JPanel();
    List listOfShemes = new List();
    GuiScheme currentScheme;
    ScrollPane sp = new ScrollPane();
    Assembler asm;
    CPURegister cpuregs;
    public static JDialog dialogRegs = new JDialog();
    Memory guimem;
    public static JDialog dialogMem = new JDialog();

    public void update(Graphics g) {
        paint(g);
    }

    public Main() {
        super("Aca");
       
        Adr1.init();
        Bus1.init();
        Counter.init();
        Exec1.init();
        Exec2.init();
        Exec3.init();
        Exec4.init();
        Fetch1.init();
        Fetch2.init();
        Fetch3.init();
        Intr1.init();
        Intr2.init();
        Intr3.init();
        Mem1.init();
        Mem2.init();
        Oper1.init();
        Uprav1.init();

        // GUI
        Adr1.gui();
        Bus1.gui();
        Counter.gui();
        Exec1.gui();
        Exec2.gui();
        Exec3.gui();
        Exec4.gui();
        Fetch1.gui();
        Fetch2.gui();
        Fetch3.gui();
        Intr1.gui();
        Intr2.gui();
        Intr3.gui();
        Mem1.gui();
        Mem2.gui();
        Oper1.gui();
        Uprav1.gui();

        Adr1.connect();
        Bus1.connect();
        Counter.connect();
        Exec1.connect();
        Exec2.connect();
        Exec3.connect();
        Exec4.connect();
        Fetch1.connect();
        Fetch2.connect();
        Fetch3.connect();
        Intr1.connect();
        Intr2.connect();
        Intr3.connect();
        Mem1.connect();
        Mem2.connect();
        Oper1.connect();
        Uprav1.connect();

        // stavi se u mem11
        //Mem11.writeMEM(0, 192);
        //Mem11.writeMEM(1, 192);
        //Mem11.writeMEM(2, 100);
        //Mem11.writeMEM(3, 194);
        //Mem11.writeMEM(4, 1);
        //Mem11.writeMEM(5, 193);
        //Mem11.writeMEM(6, 1);
        //Mem11.writeMEM(7, 142);
        //Mem11.writeMEM(8, 192);
        //Mem11.writeMEM(9, 192);
        //Mem11.writeMEM(10, 200);
        //Mem11.writeMEM(11, 194);
        //Mem11.writeMEM(12, 2);
        //Mem11.writeMEM(13, 193);
        //Mem11.writeMEM(14, 2);
        //Mem11.writeMEM(15, 143);
        //Mem11.writeMEM(16, 192);
        //Mem11.writeMEM(17, 192);
        //Mem11.writeMEM(18, 15);
        //Mem11.writeMEM(19, 66);
        //Mem11.writeMEM(20, 2);
        //Mem11.writeMEM(21, 196);
        //Mem11.writeMEM(22, 192);
        //Mem11.writeMEM(23, 30);
        //Mem11.writeMEM(24, 145);

        //Mem11.writeMEM(50, 196);
        //Mem11.writeMEM(51, 192);
        //Mem11.writeMEM(52, 5);
        //Mem11.writeMEM(53, 197);
        //Mem11.writeMEM(54, 192);
        //Mem11.writeMEM(55, 10);
        //Mem11.writeMEM(56, 129);

        //Mem11.writeMEM(104, 0);
        //Mem11.writeMEM(105, 50);

        // Debuger d=new Debuger();

        // GUI
        LogicalComponent.initialise();
        
        cpuregs = new CPURegister();
        guimem = new Memory();
        
        phase.setText(st.getDescAt(Counter.mPC().getIntVal()) == null ? phase.getText() : st.getDescAt(Counter.mPC().getIntVal()));
        String s1 = st.getStepsAt(Counter.mPC().getIntVal()) == null ? signs.getText() : st.getStepsAt(Counter.mPC().getIntVal());
        s1 = "<html>" + s1 + "</html>";
        signs.setText(s1);
        signs.setAlignmentX(CENTER_ALIGNMENT);
       
        currentScheme = Bus1.getGui();
        diagram.setSize(860, 500);
        cpuregs.init();
        guimem.init();

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        sp.setMinimumSize(new Dimension(800, 600));
        sp.setSize(new Dimension(800, 600));
        sp.add(currentScheme);
        add("Center", sp);

        Dimension d = new Dimension(160, 620);
        east.setMaximumSize(d);
        east.setMinimumSize(d);
        east.setPreferredSize(d);
        east.setSize(d);

        northeast.setLayout(new GridLayout(2, 1));
        JPanel northeastI = new JPanel();
        northeastI.setLayout(new BoxLayout(northeastI, BoxLayout.Y_AXIS));
        CPUclock.setAlignmentX(CENTER_ALIGNMENT);
        northeastI.add(CPUclock);
        Tcpu.setAlignmentX(CENTER_ALIGNMENT);
        northeastI.add(Tcpu);
        PC.setAlignmentX(CENTER_ALIGNMENT);
        northeastI.add(PC);
        northeast.add(northeastI);
       
        CLK.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

             	if(Counter.mPC().getIntVal() == 0) {
            		for(int i = 0; i < Disassembler.cnt; i++) {
            			if(Fetch1.PC().getIntVal() == Disassembler.PCvalue[i]) 
            				cnt = i;
            		}
            	}
                Highlighter h = asmtext.getHighlighter();
        		h.removeAllHighlights();
        		try {
        			
        			h.addHighlight(asmtext.getLineStartOffset(cnt), asmtext.getLineEndOffset(cnt), DefaultHighlighter.DefaultPainter);
        			scrolltxt.getVerticalScrollBar().setValue(cnt*16);
        		}catch (Exception e) {
        		}
         		
                LogicalComponent.CLK();

                CPUclock.setText("CPU clock = " + LogicalComponent.globalClock);

                String step = Integer.toHexString(Counter.mPC()
                        .getIntVal());

                Tcpu.setText("mPC = " + step);

                PC.setText("PC = " + Integer.toHexString(Fetch1.PC().getIntVal()));

                //OVO DA SE IZMENIIIIIIIIIII
                phase.setText(st.getDescAt(Counter.mPC().getIntVal()) == null ? phase.getText() : st.getDescAt(Counter.mPC().getIntVal()));
                String s1 = st.getStepsAt(Counter.mPC().getIntVal()) == null ? signs.getText() : st.getStepsAt(Counter.mPC().getIntVal());
                s1 = "<html>" + s1 + "</html>";
                signs.setText(s1);


                currentScheme.repaint();


                // cpuregs.repaint(); suvisno je jer kad se otvori dijalog tada
                // ne moze da se krece kroz simulaciju
                // pa ne moze da ispadnu lose brojke u pregledu registara ako se
                // ne repaintuje

                if (Exec2.START().getBoolVal() == false) {
                    CLK.setEnabled(false);
                    INS.setEnabled(false);
                    PRG.setEnabled(false);
                    GOTO.setEnabled(false);
                }
            }
        });
        CLK.setAlignmentX(CENTER_ALIGNMENT);
     //   CLK.setIcon(new ImageIcon(Class.class
		//		.getResource("images/nextClk.png")));
    //    Dimension dim = new Dimension(250,44);
      //  CLK.setPreferredSize(dim);
        northeastI.add(CLK);


        INS.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                // par kloka da izadje iz T00
            	if(Counter.mPC().getIntVal() == 0) {
            		for(int i = 0; i < Disassembler.cnt; i++) {
            			if(Fetch1.PC().getIntVal() == Disassembler.PCvalue[i]) 
            				cnt = i;
            		}
            	}
                Highlighter h = asmtext.getHighlighter();
        		h.removeAllHighlights();
        		try {
        			
        			h.addHighlight(asmtext.getLineStartOffset(cnt), asmtext.getLineEndOffset(cnt), DefaultHighlighter.DefaultPainter);
        			scrolltxt.getVerticalScrollBar().setValue(cnt*16);
        		}catch (Exception e) {
        		}
                LogicalComponent.CLK();
                CPUclock.setText("CPU clock = " + LogicalComponent.globalClock);
                Tcpu.setText("mPC = " + Integer.toHexString(Counter.mPC().getIntVal()));
                PC.setText("PC = " + Integer.toHexString(Fetch1.PC().getIntVal()));
                currentScheme.repaint();
                if (Exec2.START().getBoolVal() == false) {
                    CLK.setEnabled(false);
                    INS.setEnabled(false);
                    PRG.setEnabled(false);
                    GOTO.setEnabled(false);
                }
                LogicalComponent.CLK();
                CPUclock.setText("CPU clock = " + LogicalComponent.globalClock);
                Tcpu.setText("Tcpu = " + Integer.toHexString(Counter.mPC().getIntVal()));
                PC.setText("PC = " + Integer.toHexString(Fetch1.PC().getIntVal()));
                currentScheme.repaint();
                if (Exec2.START().getBoolVal() == false) {
                    CLK.setEnabled(false);
                    INS.setEnabled(false);
                    PRG.setEnabled(false);
                    GOTO.setEnabled(false);
                }
                // vrti se dok ne dodje do T00
                while ((Counter.mPC().getIntVal() != 0) && (Exec2.START().getBoolVal() == true)) {
                    LogicalComponent.CLK();
                    CPUclock.setText("CPU clock = " + LogicalComponent.globalClock);
                    Tcpu.setText("Tcpu = " + Integer.toHexString(Counter.mPC().getIntVal()));
                    PC.setText("PC = " + Integer.toHexString(Fetch1.PC().getIntVal()));
                    currentScheme.repaint();
                }
                if (Exec2.START().getBoolVal() == false) {
                    CLK.setEnabled(false);
                    INS.setEnabled(false);
                    PRG.setEnabled(false);
                    GOTO.setEnabled(false);
                }
                phase.setText(st.getDescAt(Counter.mPC().getIntVal()) == null ? phase.getText() : st.getDescAt(Counter.mPC().getIntVal()));
                String s1 = st.getStepsAt(Counter.mPC().getIntVal()) == null ? signs.getText() : st.getStepsAt(Counter.mPC().getIntVal());
                s1 = "<html>" + s1 + "</html>";
                signs.setText(s1);
            }
        });
        INS.setAlignmentX(CENTER_ALIGNMENT);
        northeastI.add(INS);

        PRG.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
 
                while (Exec2.START().getBoolVal() == true) {
                    LogicalComponent.CLK();
                    CPUclock.setText("CPU clock = " + LogicalComponent.globalClock);
                    Tcpu.setText("Tcpu = " + Integer.toHexString(Counter.mPC().getIntVal()));
                    PC.setText("PC = " + Integer.toHexString(Fetch1.PC().getIntVal()));
                    currentScheme.repaint();
                }
                CLK.setEnabled(false);
                INS.setEnabled(false);
                PRG.setEnabled(false);
                GOTO.setEnabled(false);
            }
        });
        PRG.setAlignmentX(CENTER_ALIGNMENT);
        northeastI.add(PRG);

        GOTO.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                String s = end.getText();
                int n = -1;
                try {
                    n = Integer.parseInt(s);
                    if (n == -1) {
                        end.setText("");
                        return;
                    }
                    if (n == 0) {
                        //samo reset sistema bez memorije
                        //LogicalComponent.resetSimulation();
                        LogicalComponent.initMemory = false;
                        LogicalComponent.initialise();

                        // Podesi labele
                        CPUclock.setText("CPU clock = " + LogicalComponent.globalClock);
                        Tcpu.setText("Tcpu = " + Integer.toHexString(Counter.mPC().getIntVal()));
                        PC.setText("PC =" + Integer.toHexString(Fetch1.PC().getIntVal()));
                        end.setText("");
                        phase.setText(st.getDescAt(Counter.mPC().getIntVal()) == null ? phase.getText() : st.getDescAt(Counter.mPC().getIntVal()));
                        String s1 = st.getStepsAt(Counter.mPC().getIntVal()) == null ? signs.getText() : st.getStepsAt(Counter.mPC().getIntVal());
                        s1 = "<html>" + s1 + "</html>";
                        signs.setText(s1);

                        // Ucitaj na pocetku program iz text-area
                        //String asmcode = asmtext.getText();
                        //asm.asembly(asmcode);

                        CLK.setEnabled(true);
                        INS.setEnabled(true);
                        PRG.setEnabled(true);
                        GOTO.setEnabled(true);

                    } else if (n < LogicalComponent.globalClock) {
                        int i = 0;
                        //resetuje se sistem
                        LogicalComponent.initMemory = false;
                        LogicalComponent.initialise();

                        while (Exec2.START().getBoolVal() == true && (i < n)) {
                            LogicalComponent.CLK();
                            CPUclock.setText("CPU clock = " + LogicalComponent.globalClock);
                            Tcpu.setText("Tcpu = " + Integer.toHexString(Counter.mPC().getIntVal()));
                            PC.setText("PC = " + Integer.toHexString(Fetch1.PC().getIntVal()));
                            phase.setText(st.getDescAt(Counter.mPC().getIntVal()) == null ? phase.getText() : st.getDescAt(Counter.mPC().getIntVal()));
                            String s1 = st.getStepsAt(Counter.mPC().getIntVal()) == null ? signs.getText() : st.getStepsAt(Counter.mPC().getIntVal());
                            s1 = "<html>" + s1 + "</html>";
                            signs.setText(s1);

                            i++;
                        }

                    } else if (n > LogicalComponent.globalClock) {
                        while (Exec2.START().getBoolVal() == true && LogicalComponent.globalClock < n) {
                            LogicalComponent.CLK();
                            CPUclock.setText("CPU clock = " + LogicalComponent.globalClock);
                            Tcpu.setText("Tcpu = " + Integer.toHexString(Counter.mPC().getIntVal()));
                            PC.setText("PC = " + Integer.toHexString(Fetch1.PC().getIntVal()));
                            phase.setText(st.getDescAt(Counter.mPC().getIntVal()) == null ? phase.getText() : st.getDescAt(Counter.mPC().getIntVal()));
                            String s1 = st.getStepsAt(Counter.mPC().getIntVal()) == null ? signs.getText() : st.getStepsAt(Counter.mPC().getIntVal());
                            s1 = "<html>" + s1 + "</html>";
                            signs.setText(s1);
                        }
                    } else {
                        //nista jer se ostaje u istom kloku
                    }

                    end.setText("");
                    // cpuregs.repaint(); suvisno je jer kad se otvori dijalog tada
                    // ne moze da se krece kroz simulaciju
                    // pa ne moze da ispadnu lose brojke u pregledu registara ako se
                    // ne repaintuje

                    if (Exec2.START().getBoolVal() == false) {
                        CLK.setEnabled(false);
                        INS.setEnabled(false);
                        PRG.setEnabled(false);
                        GOTO.setEnabled(false);
                    }
                    currentScheme.repaint();

                } catch (NumberFormatException e) {
                    end.setText("");
                    return;//ovde eventualno ubaciti da vrati prozor koji kaze da nije lepo uneto
                    //catch postoji samo da ne bi pukla aplikacija zbog unetih slova ili hex brojeva 
                }
            }
        });
        GOTO.setAlignmentX(LEFT_ALIGNMENT);
        JPanel GOTOpanel = new JPanel(new GridLayout(1, 2));
        GOTOpanel.add(GOTO);
        end.setAlignmentX(RIGHT_ALIGNMENT);
        GOTOpanel.add(end);
       
        northeastI.add(GOTOpanel);


        JPanel northeastII = new JPanel();
        northeastII.setBorder(new TitledBorder(UIManager
				.getBorder("TitledBorder.border"), "Control unit info",
				TitledBorder.CENTER, TitledBorder.TOP, null, new Color(0, 0,
						255)));
        northeastII.setLayout(new BoxLayout(northeastII, BoxLayout.Y_AXIS));
        // Dodati labelu koja kazuje fazu
        phaseName.setAlignmentX(CENTER_ALIGNMENT);
        northeastII.add(phaseName);
        phaseName.setFont(new Font("D", 10, 13));
        phase.setAlignmentX(CENTER_ALIGNMENT);
        northeastII.add(phase);

        // Dodati labelu koja kazuje nacin adresiranja
        signsName.setAlignmentX(CENTER_ALIGNMENT);
        northeastII.add(signsName);
        signsName.setFont(new Font("D", 10, 13));
        signs.setMinimumSize(new Dimension(10, 40));
        //signs.setAlignmentX(CENTER_ALIGNMENT);

        northeastII.add(signs);

        northeast.add(northeastII);

        asmtext.setText("");
        asmtext.setAlignmentX(CENTER_ALIGNMENT);
        scrolltxt.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrolltxt.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        
        load.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
           /* 	asm = new Assembler(asmtext.getText(), null);
                int adr = asm.getStartOfCode();
                for (Object o : asm.getCode()) {
                    int data = (int) o;
                    Mem1.getMEM().write(adr++, data);
                }

                JOptionPane.showMessageDialog(load.getParent().getParent()
                        .getParent(), "Program ucitan u memoriju",
                        "Ucitavanje programa", JOptionPane.PLAIN_MESSAGE);
                asmtext.setText(Assembler.asmProg.toString());
                new Disassembler(asm.getCode(), asm.getStartOfCode());*/
            }
        });
        load.setAlignmentX(CENTER_ALIGNMENT);
        load.setToolTipText("Pritisnite da prevedete program");
        btnOpenAsm.setAlignmentX(CENTER_ALIGNMENT);
        btnOpenAsm.setIcon(new ImageIcon(Class.class
				.getResource("/tmhm/images/btnCompile.png")));
        asmtext.setEditable(false);
        btnOpenAsm.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				btnOpenAsmActionPerformed(evt);
			}
		});
        
       
        
        memory.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                // JFrame mem = new JFrame();

                // mem.setBounds(currentScheme.getX() + currentScheme.getWidth()
                // 8, currentScheme.getY(), 600, 600);

                // mem.setLayout(new GridLayout(8 * 32, 8 * 32));

                // mem.getContentPane().setBackground(Color.WHITE);

                // for (int i = 0; i < 64 * 1024; i++)
                // mem.add(new JLabel(" mem" + i + ": " + Mem1.readMEM(i)));

                // mem.setVisible(true);

                dialogMem.setVisible(true);
                currentScheme.repaint();

            }
        });
        memory.setAlignmentX(CENTER_ALIGNMENT);

        registers.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                // JFrame regs = new JFrame();

                // regs.setBounds(currentScheme.getX() +
                // currentScheme.getWidth()
                // / 8, currentScheme.getY(), 600, 600);

                // regs.setLayout(new GridLayout(8, 8));

                // regs.getContentPane().setBackground(Color.WHITE);

                // for (int i = 0; i < 64; i++)
                // regs.add(new JLabel(" Reg" + i + ": " + Adr.readGPR(i)));

                dialogRegs.setVisible(true);
                currentScheme.repaint();

            }
        });
        registers.setAlignmentX(CENTER_ALIGNMENT);

        reset.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                //LogicalComponent.resetSimulation();
                LogicalComponent.initMemory = true;
                LogicalComponent.initialise();
                
                scrolltxt.getVerticalScrollBar().setValue(0);
                Highlighter h = asmtext.getHighlighter();
        		h.removeAllHighlights();
        	//	Assembler.ukid = 0;
        		
                // Podesi labele
                CPUclock.setText("CPU clock = " + LogicalComponent.globalClock);
                Tcpu.setText("mPC = " + Integer.toHexString(Counter.mPC().getIntVal()));
                PC.setText("PC =" + Integer.toHexString(Fetch1.PC().getIntVal()));
                end.setText("");
                phase.setText(st.getDescAt(Counter.mPC().getIntVal()) == null ? phase.getText() : st.getDescAt(Counter.mPC().getIntVal()));
                String s1 = st.getStepsAt(Counter.mPC().getIntVal()) == null ? signs.getText() : st.getStepsAt(Counter.mPC().getIntVal());
                s1 = "<html>" + s1 + "</html>";
                signs.setText(s1);

                // Ucitaj na pocetku program iz text-area
                //String asmcode = asmtext.getText();
                //asm.asembly(asmcode);

                JOptionPane.showMessageDialog(btnOpenAsm.getParent().getParent()
                        .getParent(), "Simulacija resetovana",
                        "Resetovanje simulacije...", JOptionPane.PLAIN_MESSAGE);
                CLK.setEnabled(true);
                INS.setEnabled(true);
                PRG.setEnabled(true);
                GOTO.setEnabled(true);
                currentScheme.repaint();

            }
        });
        reset.setAlignmentX(CENTER_ALIGNMENT);

        resetnomem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                //LogicalComponent.resetSimulation();
                LogicalComponent.initMemory = false;
                LogicalComponent.initialise();
                
                scrolltxt.getVerticalScrollBar().setValue(0);
                Highlighter h = asmtext.getHighlighter();
        		h.removeAllHighlights();
        	//	Assembler.ukid = 0;
        		
                // Podesi labele
                CPUclock.setText("CPU clock = " + LogicalComponent.globalClock);
                Tcpu.setText("Tcpu = " + Integer.toHexString(Counter.mPC().getIntVal()));
                PC.setText("PC =" + Integer.toHexString(Fetch1.PC().getIntVal()));
                end.setText("");
                phase.setText(st.getDescAt(Counter.mPC().getIntVal()) == null ? phase.getText() : st.getDescAt(Counter.mPC().getIntVal()));
                String s1 = st.getStepsAt(Counter.mPC().getIntVal()) == null ? signs.getText() : st.getStepsAt(Counter.mPC().getIntVal());
                s1 = "<html>" + s1 + "</html>";
                signs.setText(s1);

                // Ucitaj na pocetku program iz text-area
                //String asmcode = asmtext.getText();
                //asm.asembly(asmcode);

                JOptionPane.showMessageDialog(btnOpenAsm.getParent().getParent()
                        .getParent(), "Simulator resetovan, memorija nepromenjena.",
                        "Resetovanje simulacije...", JOptionPane.PLAIN_MESSAGE);
                CLK.setEnabled(true);
                INS.setEnabled(true);
                PRG.setEnabled(true);
                GOTO.setEnabled(true);
                currentScheme.repaint();

            }
        });
        resetnomem.setAlignmentX(CENTER_ALIGNMENT);

        southeast.setLayout(new BoxLayout(southeast, BoxLayout.Y_AXIS));

        // Dodat scroll bar za asemblerski tekst
        //
        asmtxt.setAlignmentX(CENTER_ALIGNMENT);
       // southeast.add(asmtxt);

        scrolltxt = new JScrollPane(asmtext);
        scrolltxt.setName("KOD");
        scrolltxt.setAlignmentX(CENTER_ALIGNMENT);
        southeast.add(scrolltxt);

       // southeast.add(load);
        southeast.add(btnOpenAsm);

        east.setLayout(new GridLayout(2, 1));
        east.add(northeast);
        east.add(southeast);
        add("East", east);
        southeast.setBorder(new TitledBorder(UIManager
				.getBorder("TitledBorder.border"), "Assembly code",
				TitledBorder.CENTER, TitledBorder.TOP, null, new Color(0, 0,
						255)));

        listOfShemes.add("Procesor");
        listOfShemes.add("     Operaciona Jedinica");
        listOfShemes.add("          Addr");
        listOfShemes.add("          Bus");
        listOfShemes.add("          Exec 1");
        listOfShemes.add("          Exec 2");
        listOfShemes.add("          Exec 3");
        listOfShemes.add("          Exec 4");
        listOfShemes.add("          Fetch 1");
        listOfShemes.add("          Fetch 2");
        listOfShemes.add("          Fetch 3");
        listOfShemes.add("          Intr 1");
        listOfShemes.add("          Intr 2");
        listOfShemes.add("          Intr 3");
        listOfShemes.add("     Upravljacka Jedinica");
        listOfShemes.add("          MikroMemorija");
        listOfShemes.add("          Operacioni signals");
        listOfShemes.add("          Upravljacki signals");
        listOfShemes.add("Memorija");
        listOfShemes.add("      Operaciona jedinica");
        listOfShemes.add("      Upravljacka jedinica");

        listOfShemes.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent arg0) {

                sp.remove(currentScheme);
                if (listOfShemes.getSelectedItem().equals("          Addr") || listOfShemes.getSelectedItem().equals("Procesor") || listOfShemes.getSelectedItem().equals("     Operaciona Jedinica")) {
                    currentScheme = Adr1.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "          Bus")) {
                    currentScheme = Bus1.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "          MikroMemorija") || listOfShemes.getSelectedItem().equals(
                        "     Upravljacka Jedinica")) {
                    currentScheme = Counter.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "          Exec 1")) {
                    currentScheme = Exec1.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "          Exec 2")) {
                    currentScheme = Exec2.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "          Exec 3")) {
                    currentScheme = Exec3.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "          Exec 4")) {
                    currentScheme = Exec4.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "          Fetch 1")) {
                    currentScheme = Fetch1.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "          Fetch 2")) {
                    currentScheme = Fetch2.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "          Fetch 3")) {
                    currentScheme = Fetch3.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "          Intr 1")) {
                    currentScheme = Intr1.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "          Intr 2")) {
                    currentScheme = Intr2.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "          Intr 3")) {
                    currentScheme = Intr3.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "      Operaciona jedinica") || listOfShemes.getSelectedItem().equals(
                        "Memorija")) {
                    currentScheme = Mem1.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "      Upravljacka jedinica")) {
                    currentScheme = Mem2.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "          Operacioni signals")) {
                    currentScheme = Oper1.getGui();
                } else if (listOfShemes.getSelectedItem().equals(
                        "          Upravljacki signals")) {
                    currentScheme = Uprav1.getGui();
                }
                sp.add(currentScheme);
                repaint();
                validate();
            }
        });
        west.setLayout(new BorderLayout());
        west.add(listOfShemes, BorderLayout.CENTER);
        menu.setLayout(new GridLayout(4, 1));
        menu.add(memory);
        menu.add(registers);
        menu.add(reset);
        menu.add(resetnomem);
        west.add(menu, BorderLayout.SOUTH);
        add("West", west);
        ;
        validate();
        setBounds(0, 0, sp.getWidth() + listOfShemes.getWidth()
                + asmtext.getWidth() + 320, sp.getHeight() + 40);
        this.setMinimumSize(new Dimension(800, 600));
        setVisible(true);

        // Ucitaj na pocetku default program
        //String asmcode = asmtext.getText();
        //asm.asembly(asmcode);

        dialogRegs.setResizable(false);
        dialogRegs.setTitle("CPU registri");
        dialogRegs.setModal(true);
        dialogRegs.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent arg0) {
                dialogRegs.setVisible(false);
                currentScheme.repaint();
            }
        });
        cpuregs.setSadrzalacRegistara(dialogRegs);
        dialogRegs.add(cpuregs);
        dialogRegs.setSize(600, 600);
        dialogRegs.setLocation(100, 100);
        dialogRegs.setVisible(false);

        dialogMem.setResizable(false);
        dialogMem.setTitle("Pregled Memorije");
        dialogMem.setModal(true);
        dialogMem.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent arg0) {
                dialogMem.setVisible(false);
                currentScheme.repaint();
            }
        });
        guimem.setSadrzalacMemorije(dialogMem);
        dialogMem.add(guimem);
        dialogMem.setSize(500, 300);
        dialogMem.setLocation(100, 100);
        dialogMem.setVisible(false);
        
        
        
        
        drawCanvas.setBackground(new java.awt.Color(255, 255, 255));
        drawCanvas.setBorder(new TitledBorder(UIManager
				.getBorder("TitledBorder.border"), "drawButton",
				TitledBorder.CENTER, TitledBorder.TOP, null, new Color(0, 0,
						255)));

        signal1.setFont(new java.awt.Font("Tahoma", 1, 11));
        signal1.setText("signal");

        signal2.setFont(new java.awt.Font("Tahoma", 1, 11));
        signal2.setText("signal");

        signal3.setFont(new java.awt.Font("Tahoma", 1, 11));
        signal3.setText("signal");

        signal4.setFont(new java.awt.Font("Tahoma", 1, 11));
        signal4.setText("signal");

        signal5.setFont(new java.awt.Font("Tahoma", 1, 11));
        signal5.setText("signal");

        javax.swing.GroupLayout platnoLayout = new javax.swing.GroupLayout(drawCanvas);
        drawCanvas.setLayout(platnoLayout);
        platnoLayout.setHorizontalGroup(
            platnoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(platnoLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(platnoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(signal2, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(signal4, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(signal1, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(signal3, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(signal5, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(514, Short.MAX_VALUE))
        );
        platnoLayout.setVerticalGroup(
            platnoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(platnoLayout.createSequentialGroup()
                .addGap(54, 54, 54)
                .addComponent(signal2, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(67, 67, 67)
                .addComponent(signal1, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(64, 64, 64)
                .addComponent(signal3, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(65, 65, 65)
                .addComponent(signal5, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 79, Short.MAX_VALUE)
                .addComponent(signal4, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(20, 20, 20))
        );

        signals.setBackground(new java.awt.Color(255, 255, 255));
        signals.setBorder(new TitledBorder(UIManager
				.getBorder("TitledBorder.border"), "Signal",
				TitledBorder.CENTER, TitledBorder.TOP, null, new Color(0, 0,
						255)));

        drawTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
            	 {"MOST1_2", null},    {"MOST1_3", null},      {"MOST2_1", null},
            	 {"MOST3_2", null},   {"rdCPU", null},   {"wrCPU", null},
            	 {"ldMDR", null},   {"mxMDR", null},     {"MDRout1", null},
            	 {"eMDR", null},    {"ldMAR", null},     {"incMAR", null},
            	 {"eMAR", null},   {"ldDWL", null},      {"ldDWH", null},
            	 {"DWout3", null},   {"wrGPR", null},    {"GPRout1", null},
            	 {"ldGPRAR", null},    {"incGPRAR", null},      {"ldSP", null},
            	 {"SPout2", null},   {"incSP", null},   {"decSP", null},
            	 {"ldCW", null},   {"CWout3", null},    {"ADDout2", null},
            	 {"ldPC", null},    {"incPC", null},      {"PCHout3", null},
            	 {"PCLout3", null},   {"PCout1", null},   {"ldIR0", null},
            	 {"ldIR1", null},   {"ldIR2", null},    {"ldIR3", null},
            	 {"IRPOMout3", null},    {"IRJAout2", null},      {"IRDAout3", null},
            	 {"IRBRout3", null},   {"add", null},   {"sub", null},
            	 {"inc", null},   {"dec", null},    {"and", null},
            	 {"or", null},    {"xor", null},      {"not", null},
            	 {"ALUout1", null},   {"ldAB", null},   {"ABout3", null},
            	 {"shr", null},   {"shl", null},    {"ldBB", null},
            	 {"BBout2", null},   {"ldAW", null},    {"AWout3", null},
            	 {"AWHout3", null},    {"ldBW", null},      {"BWout2", null},
            	 {"ldPSWH", null},   {"ldPSWL", null},   {"ldN", null},
            	 {"ldZ", null},   {"ldC", null},    {"ldV", null},
            	 {"ldL", null},    {"stPSWI", null},      {"clPSWI", null},
            	 {"stPSWT", null},   {"clPSWT", null},   {"PSWHout3", null},
            	 {"PSWLout3", null},   {"clSTART", null},    {"ldIMR", null},
            	 {"IMRout2", null},    {"ldBR", null},      {"IVTDSPout3", null},
            	 {"ldIVTP", null},   {"IVTPout1", null},   {"UINTout3", null},
            	 {"UEXTout3", null},   {"stPRCOD", null},    {"stPRADR", null},   	 
            	 {"stPRINS", null},    {"clPRCOD", null},      {"clPRADR", null},
            	 {"clPRINS", null},   {"clPRINM", null},   {"clINTR", null},

            },
            new String [] {
                "Signal", "Check"
            }
        )  {
			Class[] types = new Class [] {
                     java.lang.String.class, java.lang.Boolean.class
                 };

                 public Class getColumnClass(int columnIndex) {
                     return types [columnIndex];
                 }
        });
        JScroolPanelDraw.setViewportView(drawTable);
        drawTable.getColumnModel().getColumn(0).setResizable(false);
        drawTable.getColumnModel().getColumn(1).setResizable(false);

        drawButton.setText("drawButton");
        drawButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
             //   drawActionPerformed(evt);
            }
        });

        
        javax.swing.GroupLayout signaliLayout = new javax.swing.GroupLayout(signals);
        signals.setLayout(signaliLayout);
        signaliLayout.setHorizontalGroup(
            signaliLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(signaliLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(signaliLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(JScroolPanelDraw, javax.swing.GroupLayout.PREFERRED_SIZE, 201, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(drawButton, javax.swing.GroupLayout.DEFAULT_SIZE, 201, Short.MAX_VALUE))
                .addContainerGap())
        );
        signaliLayout.setVerticalGroup(
            signaliLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, signaliLayout.createSequentialGroup()
                .addComponent(JScroolPanelDraw, javax.swing.GroupLayout.DEFAULT_SIZE, 332, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(drawButton, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        Navigation.setBackground(new java.awt.Color(255, 255, 255));
        Navigation.setBorder(new TitledBorder(UIManager
				.getBorder("TitledBorder.border"), "Navigation",
				TitledBorder.CENTER, TitledBorder.TOP, null, new Color(0, 0,
						255)));
        Navigation.setLayout(new java.awt.GridLayout(1, 0));

        leftButton.setText("Left");
        leftButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
               // leftButtonActionPerformed(evt);
            }
        });
        Navigation.add(leftButton);

        rightButton.setText("Right");
        rightButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
               // rightButtonActionPerformed(evt);
            }
        });
        Navigation.add(rightButton);

        javax.swing.GroupLayout diagramLayout = new javax.swing.GroupLayout(diagram.getContentPane());
        diagram.getContentPane().setLayout(diagramLayout);
        diagramLayout.setHorizontalGroup(
            diagramLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(diagramLayout.createSequentialGroup()
                .addComponent(drawCanvas, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(diagramLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(diagramLayout.createSequentialGroup()
                        .addComponent(Navigation, 0, 223, Short.MAX_VALUE)
                        .addContainerGap(20, Short.MAX_VALUE))
                    .addGroup(diagramLayout.createSequentialGroup()
                        .addComponent(signals, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap())))
        );
        diagramLayout.setVerticalGroup(
            diagramLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(drawCanvas, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, diagramLayout.createSequentialGroup()
                .addComponent(signals, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(Navigation, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE))
        );
        
        
        
        file.setText("File");

        jMenuItem1.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItem1.setText(" New");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });
        file.add(jMenuItem1);
        
        menuBar.add(file);
        setJMenuBar(menuBar);
        
        view.setText("View");
        jMenuItem2.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_T, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItem2.setText(" Time Diagram");
        jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem2ActionPerformed(evt);
            }
        });
        view.add(jMenuItem2);
        
        menuBar.add(view);
        setJMenuBar(menuBar);
        
        help.setText("Help");

        jMenuItem3.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_B, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItem3.setText(" About");
        jMenuItem3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem3ActionPerformed(evt);
            }
        });
        help.add(jMenuItem3);

        menuBar.add(help);

        setJMenuBar(menuBar);
        
    }

    
    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {
     
    }
    
    private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {
        diagram.show();
    }
    
    private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt) {
      
    }
    
    public static void main(String[] args) {

        
        
        new Main();

        // for(int i=0;i<1000;i++){
        // LogicalComponent.CLK();
        // d.debug();
        // }
        // System.out.println(Exec1.AB().getIntVal());
    }
    
    private void btnOpenAsmActionPerformed(java.awt.event.ActionEvent evt) {
    	int returnVal = fileChooserAsm.showOpenDialog(this);
    	if(returnVal == JFileChooser.APPROVE_OPTION) {
    		File file = fileChooserAsm.getSelectedFile();
    		try {
    			Assembler.asmProg = "";
    			String ime = file.getAbsolutePath();
				int index = ime.lastIndexOf("\\");
				index++;
				String fileName = ime.substring(index);
				String filePath = ime.substring(0, index);
				String filePathReverse = "";
				StringTokenizer token = new StringTokenizer(filePath, "\\");
				while (token.hasMoreTokens()) {
					filePathReverse = filePathReverse
							+ (String) token.nextToken();
					filePathReverse = filePathReverse + "/";
				}
				//System.out.println(filePathReverse + fileName);
				asmPath = filePathReverse + fileName;
				asm = new Assembler(asmPath, null);
                int adr = asm.getStartOfCode();
                for (Object o : asm.getCode()) {
                    Integer data = (Integer) o;
                    Mem1.getMEM().write(adr++, data);
                }

                CLK.setEnabled(true);
                INS.setEnabled(true);
                PRG.setEnabled(true);
                GOTO.setEnabled(true);
                
                JOptionPane.showMessageDialog(btnOpenAsm.getParent().getParent()
                        .getParent(), "Program ucitan u memoriju",
                        "Ucitavanje programa", JOptionPane.INFORMATION_MESSAGE);
                asmtext.setText(Assembler.asmProg.toString());
                new Disassembler(asm.getCode(), asm.getStartOfCode());
                scrolltxt.getVerticalScrollBar().setValue(0);
    		} catch (Exception e) {}
    	}
    }	
}
